#
#  Controller.rb
#  PNGCrush
#
#  Created by Josh Abernathy on 4/18/07.
#  Copyright (c) 2007 __MyCompanyName__. All rights reserved.
#

require 'osx/cocoa'
require 'thread'

class String
	def is_directory?
		return self[self.length-1..self.length] == "/"
	end
end

class DragView < OSX::NSImageView
	include OSX
		
	ib_outlets :noPNGsSheet, :progressSheet, :progressBar, :okButton
	
	def does_contain_valid_images?(images)
		images.size > 0
	end
	
	def images_from_directory(path)
		`cd \"#{path}\" ; ls *.png`.collect
	end
	
	def is_directory?(sender)
		NSURL.URLFromPasteboard(sender.draggingPasteboard).absoluteString.to_s.is_directory?
	end
	
	def clean_path(string)
		path = string.absoluteString.stringByReplacingPercentEscapesUsingEncoding(NSUTF8StringEncoding).to_s
		path['file://localhost'] = ''
		
		return NSString.stringWithString(path)
	end
	
	def crush(sender)
		return if @path.nil?
	
		if @path.to_s.is_directory? then
			images = images_from_directory(@path)
						
			if does_contain_valid_images?(images) then
				done = 0
				images.each do |image|
					crush_image_threaded(@path.to_s + image.chomp)
					
					Mutex.new.synchronize do
						@progressBar.incrementBy(100 / images.size)
						done = done + 1
					end
				end
				
				while done < images.size-1
					# kill time while we crush images
				end
				
				@progressBar.setDoubleValue(100.0)
				@okButton.setEnabled(true)
			else
				# there were no valid images in the directory
				NSApp.objc_send :beginSheet, @noPNGsSheet,
								:modalForWindow, self.window, 
								:modalDelegate, self, 
								:didEndSelector, nil, 
								:contextInfo, nil
			end
		else
			NSApp.objc_send :beginSheet, @progressSheet,
								:modalForWindow, self.window, 
								:modalDelegate, self, 
								:didEndSelector, nil, 
								:contextInfo, nil
		
			crush_image_threaded(@path)
			
			0.upto 100 do |i|
				@progressBar.setDoubleValue(i)
			end
			
			@okButton.setEnabled(true)
		end
	end
	
	def close_progress_sheet(sender)
		@progressSheet.orderOut(nil)
		NSApp.endSheet(@progressSheet)
		
		@okButton.setEnabled(false)
		@progressBar.setDoubleValue(0.0)
	end
	
	def close_sheet(sender)	
		@noPNGsSheet.orderOut(nil)
		NSApp.endSheet(@noPNGsSheet)
	end
	
	def crush_image_threaded(path)
		app_path = NSBundle.mainBundle.bundlePath
	
		Thread.new do
			`cd \"#{app_path}/Contents/Resources/\" ; ./optipng \"#{path}\"`
		end
	end
	
	def crush_image(path)
		app_path = NSBundle.mainBundle.bundlePath
	
		`cd \"#{app_path}/Contents/Resources/\" ; ./optipng \"#{path}\"`
	end
	
	def initWithCoder(coder)
		super_initWithCoder(coder)
		
		self.registerForDraggedTypes(NSImage.imagePasteboardTypes)
		
		@highlight = false
		
		setImage(NSImage.imageNamed("questionmark"))
				
		return self
	end
	
	def awakeFromNib
	end
	
	def application_openFile(sender, path)
		ext = path.to_s.split('.')
		
		if path.to_s.is_directory? or ext.size == 1 then
			setImage(NSImage.imageNamed("folder"))
			@path_string = path.lastPathComponent.to_s + "/"
			@path = path
		elsif ext.size == 2 and ext[1] == "png" then
			setImage(NSImage.alloc.initWithContentsOfFile(path))
			@path = path
		else
			print "Invalid image type"
		end
		
		setNeedsDisplay(true)
   end
	
	def draggingEntered(sender)			
		if (NSImage.canInitWithPasteboard(sender.draggingPasteboard) || is_directory?(sender)) && 
			sender.draggingSourceOperationMask & NSDragOperationCopy then
			
			@highlight = true
			setNeedsDisplay(true)
			
			return NSDragOperationCopy
		end
		
		return NSDragOperationNone
	end
	
	def draggingExited(sender)
		@highlight = false
		setNeedsDisplay(true)
	end
	
	def prepareForDragOperation(sender)	
		@highlight = false
		setNeedsDisplay(true)
		
		return NSImage.canInitWithPasteboard(sender.draggingPasteboard) || is_directory?(sender)
	end
	
	def performDragOperation(sender)
		if sender.draggingSource != self then			
			fileURL = NSURL.URLFromPasteboard(sender.draggingPasteboard)
			
			if is_directory?(sender) then
				image = NSImage.imageNamed("folder")
				
				@path_string = NSAttributedString.alloc.initWithString(clean_path(fileURL).lastPathComponent)
			else
				image = NSImage.alloc.initWithPasteboard(sender.draggingPasteboard)
			end
			
			@path = NSString.stringWithString(clean_path(fileURL))
			
			setImage(image)
		end
		
		setNeedsDisplay(true)
				
		return true
	end
	
	def drawRect(rect)
		super_drawRect(rect)
		
		if @highlight then
			NSColor.grayColor.set
			NSBezierPath.setDefaultLineWidth(5)
			NSBezierPath.strokeRect(rect)
		end
		
		if !@path_string.nil? then
			rect = @path_string.objc_send :boundingRectWithSize, frame.size, 
										  :options, 0
			rect.origin.x = frame.size.width/2 - rect.size.width/2
			rect.origin.y = 20
			@path_string.drawInRect(rect)
		end
	end
end
